package me.zingon.doc.service.impl;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import me.zingon.doc.dao.UserProjectDao;
import me.zingon.doc.exception.ServiceException;
import me.zingon.doc.model.UserProject;
import me.zingon.doc.service.UserService;
import me.zingon.doc.dao.UserDao;
import me.zingon.doc.model.User;
import me.zingon.doc.util.EmailUtil;
import me.zingon.doc.util.JwtUtil;
import me.zingon.doc.util.StringUtil;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
* Created by ZTCGenerator<zingon@aliyun.com> on 2018-5-31.
*/
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    UserDao userDao;

    @Autowired
    EmailUtil emailUtil;

    @Autowired
    UserProjectDao userProjectDao;

    @Value("${mail.activeUrl}")
    String activeUrl;

    @Value("${mail.subject}")
    String subject;

    @Value("${jwt.active.key}")
    String key;

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public int insert(User user){
        return userDao.insert(user);
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public int delete(User user){
        return userDao.delete(user);
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public int deleteByIds(Integer[] ids) {
        return  userDao.deleteByIds(ids);
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public int update(User user){
        return userDao.update(user);
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public User getById(Integer id){
        return userDao.getById(id);
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public List<User> list(User user){
        return userDao.list(user);
    }

    //---------


    @Override
    public String login(String loginName, String password) throws ServiceException {
        List<User> users=userDao.list(new User().setLoginName(loginName));
        if(users.size() != 1){
            throw new ServiceException("login.error");
        }
        User user = users.get(0);
        if(!DigestUtils.md5Hex(user.getSalt()+password).equals(user.getPassword())){
            throw new ServiceException("login.error");
        }
        if(user.getRoleId() == 0){
            throw new ServiceException("login.notactive");
        }

        Map<String,Object> claims=new HashMap<>(2);
        claims.put("userId",user.getId());
        claims.put("loginName",user.getLoginName());
        claims.put("nickName",user.getNickname());
        String token = JwtUtil.getToken(claims);
        return token;
    }

    @Override
    public int checkNickname(String nickname) {
        List<User> users=userDao.list(new User().setNickname(nickname).setDeleted(false));
        return users.size();
    }

    @Override
    public int checkEmail(String loginName) {
        List<User> users=userDao.list(new User().setLoginName(loginName).setDeleted(false));
        return users.size();
    }

    @Override
    public int register(User user) {
        user.setCreateDate(new Date());
        user.setUpdateDate(new Date());
        user.setRoleId(0);
        String salt = StringUtil.generateShortUuid();
        user.setSalt(salt);
        user.setPassword(DigestUtils.md5Hex(salt+user.getPassword()));
        int result = userDao.insert(user);
        Map<String,Object> claims=new HashMap<>(1);
        claims.put("id",user.getId());
        String token=JwtUtil.getToken(claims,key,60*24L);
        emailUtil.sendEmail(user.getLoginName(),activeUrl+token,subject);
        return result;
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)
    public int activeUser(String token) throws ServiceException {
        Claims claims=JwtUtil.validate(token,key);
        if(claims == null){
            throw new ServiceException("login.activerr");
        }
        Integer id = (Integer) claims.get("id");
        UserProject up=new UserProject();
        up.setUserId(id)
                .setPower("r")
                .setCreateDate(new Date())
                .setUpdateDate(new Date())
                .setDeleted(false);
        userProjectDao.insert(up.setProjectId(1));
        userProjectDao.insert(up.setId(null).setProjectId(2));
        return userDao.update(new User().setId(id).setRoleId(1));
    }
}